#include "SDLTool.h"


SDLTool::SDLTool()
{
}

SDLTool::~SDLTool()
{
}

/**
 * @brief 将指定图片加载成纹理
 * 
 * @param renderer : 2D渲染上下文
 * @param file ： 需要加载的图片
 * @return SDL_Texture* ： 返回加载的纹理
 */
SDL_Texture* SDLTool::LoadImage(SDL_Renderer *renderer, string file)
{
    SDL_Texture* tex = nullptr;
    tex = IMG_LoadTexture(renderer, file.c_str());
    if (tex == nullptr)
    {
        throw runtime_error("Failed to load image: " + file + IMG_GetError());
    }
    return tex;
}

/**
 * @brief 将指定纹理绘制到指定的2D上下文中
 * 
 * @param renderer ： 2D上下文
 * @param tex : 需要绘制的纹理
 * @param x : 绘制到指定位置的x坐标
 * @param y ： 绘制到指定位置的y坐标
 * @param clip ： 需要使用源图片的位置及大小
 */
void SDLTool::ApplySurface( SDL_Renderer *renderer, SDL_Texture *tex, int x, int y, SDL_Rect *clip = NULL)
{
    SDL_Rect pos;
    pos.x = x;
    pos.y = y;
    //Detect if we should use clip width settings or texture width
    if (clip != NULL)
    {
        pos.w = clip->w;
	    pos.h = clip->h;
    }
    else
    {
        SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
    }
    SDL_RenderCopy(renderer, tex, clip, &pos);
}

/**
 * @brief 加载字符串信息为纹理
 * 
 * @param renderer ： 2D上下文
 * @param message : 需要显示的信息
 * @param fontFile ： 使用的字体
 * @param color ： 字体颜色
 * @param fontSize ： 字体大小
 * @return SDL_Texture* ： 返回字体的纹理 
 */
SDL_Texture* SDLTool::RenderText(SDL_Renderer *renderer, string message, string fontFile, SDL_Color color, int fontSize)
{
    //Open the font
    TTF_Font *font = nullptr;
    font = TTF_OpenFont(fontFile.c_str(), fontSize);
    if (font == nullptr)
        throw std::runtime_error("Failed to load font: " + fontFile + TTF_GetError());
	
    //Render the message to an SDL_Surface, as that's what TTF_RenderText_X returns
    SDL_Surface *surf = TTF_RenderText_Blended(font, message.c_str(), color);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
    //Clean up unneeded stuff
    SDL_FreeSurface(surf);
    TTF_CloseFont(font);

    return texture;
}


/**
 * @brief 初始化SDL环境
 * 
 * @return int ： 0：OK -1:Err
 */
int SDLTool::SDLInit()
{
    static bool sdlIsInit = false;

    if( sdlIsInit == true )
    {
        return 0;
    }

    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        cout << SDL_GetError() << endl;
        return -1;
    }

    if (TTF_Init() == -1)
    {
        cout << TTF_GetError() << endl;
        return -1;
    }
    sdlIsInit = true;

    cout << "SDL INIT OK" << endl;

    return 0;
}